#include "vagsdk_util.h"
#include "logger.h"



// 辅助函数：从Java对象中提取必填字符串字段
void ExtractStringField(JNIEnv *env, jobject obj, jfieldID fieldID, char* dest, size_t destSize, const char* errorMsg) {
    jstring fieldString = (jstring) env->GetObjectField(obj, fieldID);
    CHECK_NULL_RETURN_THROW_API_EX(env, fieldString, errorMsg, {});

    const char *pField = env->GetStringUTFChars(fieldString, JNI_FALSE);
    if (pField == nullptr) {
        THROW_VAG_EX(env, errorMsg);
        env->DeleteLocalRef(fieldString);
        return;
    }

    strncpy(dest, pField, destSize - 1);
    dest[destSize - 1] = '\0'; // 确保字符串以空字符结尾

    env->ReleaseStringUTFChars(fieldString, pField);
    env->DeleteLocalRef(fieldString);
}

// 辅助函数：从Java对象中提取可选字符串字段
void ExtractOptionalStringField(JNIEnv *env, jobject obj, jfieldID fieldID, char* dest, size_t destSize) {
    jstring fieldString = (jstring) env->GetObjectField(obj, fieldID);

    if (fieldString == nullptr) {
        // 如果字段为空，则将目标字符串设为空
        dest[0] = '\0';
        return;
    }

    const char *pField = env->GetStringUTFChars(fieldString, JNI_FALSE);
    if (pField == nullptr) {
        THROW_VAG_EX(env, "Failed to get string characters from JNI string");
        env->DeleteLocalRef(fieldString);
        return;
    }

    strncpy(dest, pField, destSize - 1);
    dest[destSize - 1] = '\0'; // 确保字符串以空字符结尾

    env->ReleaseStringUTFChars(fieldString, pField);
    env->DeleteLocalRef(fieldString);
}

// 解析服务器设备信息
ParseServerDevInfoPlus ParseServerDevInfo(JNIEnv *env, jobject serverDevInfoPlus) {
    ParseServerDevInfoPlus rs{};  // 初始化返回值
    JNIHandle *h = JNIHandle::GetInstance();

    // 提取设备类型
    rs.info._devicetype = env->GetIntField(serverDevInfoPlus, h->fid_deviceType);

    // 提取字符串字段
    ExtractStringField(env, serverDevInfoPlus, h->fid_devName, rs.info._dev_name, sizeof(rs.info._dev_name), "The devName can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devSerial, rs.info._dev_serial, sizeof(rs.info._dev_serial), "The devSerial can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devHardwareId, rs.info._dev_hardwareid, sizeof(rs.info._dev_hardwareid), "The devHardwareId can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devFirmwareVersion, rs.info._dev_firmwareVersion, sizeof(rs.info._dev_firmwareVersion), "The devFirmwareVersion can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devManufacturer, rs.info._dev_m_manufacturer, sizeof(rs.info._dev_m_manufacturer), "The devManufacturer can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devMode, rs.info._dev_mode, sizeof(rs.info._dev_mode), "The devMode can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devIp, rs.info._dev_ip, sizeof(rs.info._dev_ip), "The devIp can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devSoapPort, rs.info._dev_soap_port, sizeof(rs.info._dev_soap_port), "The devSoapPort can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devLoginUsername, rs.info._dev_login_username, sizeof(rs.info._dev_login_username), "The devLoginUsername can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devLoginPassword, rs.info._dev_login_password, sizeof(rs.info._dev_login_password), "The devLoginPassword can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devEthName, rs.info._dev_ethname, sizeof(rs.info._dev_ethname), "The devEthName can't be null or empty");
    ExtractStringField(env, serverDevInfoPlus, h->fid_devEthMac, rs.info._dev_ethmac, sizeof(rs.info._dev_ethmac), "The devEthMac can't be null or empty");

    return rs;
}

// 解析通道媒体信息
ParseChannelMediaInfoPlus ParseChannelMediaInfo(JNIEnv *env, jobject channelMediaInfoPlus) {
    ParseChannelMediaInfoPlus rs{};  // 初始化返回值
    JNIHandle *h = JNIHandle::GetInstance();

    // 提取字符串字段
    ExtractStringField(env, channelMediaInfoPlus, h->fid_channelId, rs.info._channle_id, sizeof(rs.info._channle_id), "The channelId can't be null or empty");

    // 允许 streamId 为空，所以不抛出异常
    ExtractOptionalStringField(env, channelMediaInfoPlus, h->fid_streamId, rs.info._stream_id, sizeof(rs.info._stream_id));

    ExtractStringField(env, channelMediaInfoPlus, h->fid_address, rs.info._address, sizeof(rs.info._address), "The address can't be null or empty");
    ExtractStringField(env, channelMediaInfoPlus, h->fid_residueUri, rs.info._residue_uri, sizeof(rs.info._residue_uri), "The residueUri can't be null or empty");

    // 提取数值字段
    rs.info._width = env->GetIntField(channelMediaInfoPlus, h->fid_width);
    rs.info._height = env->GetIntField(channelMediaInfoPlus, h->fid_height);
    rs.info._fps = env->GetFloatField(channelMediaInfoPlus, h->fid_fps);
    rs.info._bitrate = env->GetIntField(channelMediaInfoPlus, h->fid_bitrate);
    rs.info._v_codec = env->GetIntField(channelMediaInfoPlus, h->fid_vCodec);
    rs.info._stream_type = env->GetIntField(channelMediaInfoPlus, h->fid_streamType);
    rs.info._a_codec = env->GetIntField(channelMediaInfoPlus, h->fid_aCodec);
    rs.info._sample_rate = env->GetIntField(channelMediaInfoPlus, h->fid_sampleRate);
    rs.info._b_PTZ = env->GetIntField(channelMediaInfoPlus, h->fid_bPTZ);

    return rs;
}

//PTZ 回调入参，从C结构体转换为jobject对象
jobject ConvertsPtzParam(JNIEnv *env, _PTZ_param_DAU *ptzParam) {
    JNIHandle *h = JNIHandle::GetInstance();
    if (nullptr == ptzParam) {
        return nullptr;
    }
    jobject param = env->AllocObject(h->cls_ptzParamDAU);

    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_channelId, ptzParam->channle_id);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_strId, ptzParam->str_id);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_ptzConfigureToken, ptzParam->PTZConfigureToken);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_profileToken, ptzParam->ProfileToken);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_nodeToken, ptzParam->NodeToken);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_presentName, ptzParam->presentName);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_presentToken, ptzParam->presentToken);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_presentTourToken, ptzParam->presentTourToken);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_deviceUuid, ptzParam->device_uuid);

    env->SetLongField(param, h->fid_ptzParam_timeout, ptzParam->Timeout);
    env->SetBooleanField(param, h->fid_ptzParam_bPanTilt, ptzParam->b_PanTilt);
    env->SetBooleanField(param, h->fid_ptzParam_bZoomX, ptzParam->b_Zoom_X);
 
    jobject PanTilt = env->AllocObject(h->cls_ptzPoint);
    env->SetFloatField(PanTilt, h->fid_x, ptzParam->PanTilt.x);
    env->SetFloatField(PanTilt, h->fid_y, ptzParam->PanTilt.y);
    env->SetObjectField(param, h->fid_ptzParam_panTilt, PanTilt);

    env->SetFloatField(param, h->fid_ptzParam_zoomX, ptzParam->Zoom_X);
    env->SetBooleanField(param, h->fid_ptzParam_bAuxPanTilt, ptzParam->b_aux_PanTilt);
    env->SetBooleanField(param, h->fid_ptzParam_bAuxZoomX, ptzParam->b_aux_Zoom_X);

    jobject auxiliary_PanTilt = env->AllocObject(h->cls_ptzPoint);
    env->SetFloatField(auxiliary_PanTilt, h->fid_x, ptzParam->auxiliary_PanTilt.x);
    env->SetFloatField(auxiliary_PanTilt, h->fid_y, ptzParam->auxiliary_PanTilt.y);
    env->SetObjectField(param, h->fid_ptzParam_auxiliaryPanTilt, auxiliary_PanTilt);

    env->SetFloatField(param, h->fid_ptzParam_auxiliaryZoomX, ptzParam->auxiliary_Zoom_X);
    env->SetIntField(param, h->fid_ptzParam_operation, ptzParam->Operation);
    SetObjectStringFieldFromCstr(env, param, h->fid_ptzParam_videoSourceToken, ptzParam->VideoSourceToken);
    env->SetBooleanField(param, h->fid_ptzParam_bAbsolute, ptzParam->b_Absolute);
    env->SetBooleanField(param, h->fid_ptzParam_bRelative, ptzParam->b_Relative);
    env->SetBooleanField(param, h->fid_ptzParam_bContinuous, ptzParam->b_Continuous);
    env->SetFloatField(param, h->fid_ptzParam_absPosition, ptzParam->Abs_Position);
    env->SetFloatField(param, h->fid_ptzParam_absSpeed, ptzParam->Abs_Speed);
    env->SetFloatField(param, h->fid_ptzParam_relDistance, ptzParam->Rel_Distance);
    env->SetFloatField(param, h->fid_ptzParam_relSpeed, ptzParam->Rel_Speed);
    env->SetFloatField(param, h->fid_ptzParam_conSpeed, ptzParam->Con_Speed);

    jobject timg_Image = env->AllocObject(h->cls_timgImage);
    env->SetIntField(timg_Image, h->fid_brightness, ptzParam->timg_Image.brightness);
    env->SetIntField(timg_Image, h->fid_saturation, ptzParam->timg_Image.saturation);
    env->SetIntField(timg_Image, h->fid_contrast, ptzParam->timg_Image.contrast);
    env->SetIntField(timg_Image, h->fid_sharpen, ptzParam->timg_Image.sharpen);
    env->SetBooleanField(timg_Image, h->fid_wideDynamicMode, ptzParam->timg_Image.WideDynamicMode);
    env->SetFloatField(timg_Image, h->fid_wideDynamicLevel, ptzParam->timg_Image.WideDynamicLevel);
    env->SetIntField(timg_Image, h->fid_cutFilterMode, ptzParam->timg_Image.CutFilterMode);
    env->SetFloatField(timg_Image, h->fid_exposureTime, ptzParam->timg_Image.ExposureTime);
    env->SetFloatField(timg_Image, h->fid_gain, ptzParam->timg_Image.Gain);
    env->SetFloatField(timg_Image, h->fid_iris, ptzParam->timg_Image.Iris);

    env->SetObjectField(param, h->fid_ptzParam_timgImage, timg_Image);
    return param;
}

jobject ConvertsRecInfoDAU(JNIEnv* env, _Rec_Info_DAU* recInfo) {
    JNIHandle* h = JNIHandle::GetInstance();
    if (nullptr == recInfo) {
        return nullptr;
    }

    // 创建 RecInfoDAU 对象
    jobject recInfoObj = env->AllocObject(h->cls_recInfoDAU);

    // 设置 String 字段
    SetObjectStringFieldFromCstr(env, recInfoObj, h->fid_channelIdDAU, recInfo->channel_id);
    SetObjectStringFieldFromCstr(env, recInfoObj, h->fid_streamIdDAU, recInfo->stream_id);
    SetObjectStringFieldFromCstr(env, recInfoObj, h->fid_uuid, recInfo->uuid);

    // 设置 int 字段
    env->SetIntField(recInfoObj, h->fid_sourceNum, recInfo->source_num);
    env->SetIntField(recInfoObj, h->fid_subNum, recInfo->sub_num);

    return recInfoObj;
}
jobject ConvertsRecSearchEventInfo(JNIEnv* env,void* _Rec_reserve_info) {
    // 将 void* _Rec_reserve_info 转换为 Rec_Search_event_info*
    Rec_Search_event_info* recSearchEventInfo = static_cast<Rec_Search_event_info*>(_Rec_reserve_info);
    if (nullptr == recSearchEventInfo) {
        return nullptr;
    }
    JNIHandle* h = JNIHandle::GetInstance();
    // 创建 RecSearchEventInfo 对象
    jobject recSearchEventInfoObj = env->AllocObject(h->cls_recSearchEventInfoClass);
    // 设置基本字段
    env->SetIntField(recSearchEventInfoObj, h->fid_sourceIdentifier, recSearchEventInfo->source_id);
    env->SetIntField(recSearchEventInfoObj, h->fid_channelNumber, recSearchEventInfo->source_channel_Num);
    SetObjectStringFieldFromCstr(env, recSearchEventInfoObj, h->fid_channelIdentifier, recSearchEventInfo->channelid);
    SetObjectStringFieldFromCstr(env, recSearchEventInfoObj, h->fid_streamIdentifier, recSearchEventInfo->streamid);
    env->SetBooleanField(recSearchEventInfoObj, h->fid_isRecording, recSearchEventInfo->Record_flag);
    env->SetLongField(recSearchEventInfoObj, h->fid_eventStartTimestamp, recSearchEventInfo->startTimestamp);
    env->SetLongField(recSearchEventInfoObj, h->fid_eventEndTimestamp, recSearchEventInfo->endTimestamp);
    return recSearchEventInfoObj;
}
jobject ConvertsRecSearchInfo(JNIEnv* env, void* _Rec_reserve_info) {
    // 将 void* _Rec_reserve_info 转换为 Rec_Search_info
    Rec_Search_info* recSearchInfo = static_cast<Rec_Search_info*>(_Rec_reserve_info);
    if (nullptr == recSearchInfo) {
        return nullptr;
    }

    JNIHandle* h = JNIHandle::GetInstance();

    // 创建 RecSearchInfo Java 对象
    jobject recSearchInfoObj = env->AllocObject(h->cls_recSearchInfo);

    // 设置 RecSearchInfo 的 checkAll 字段
    env->SetBooleanField(recSearchInfoObj, h->fid_checkAll, recSearchInfo->cheackall);

    // 设置 RecSearchInfo 的 recSearchSize 字段
    env->SetIntField(recSearchInfoObj, h->fid_recSearchSize, recSearchInfo->__Rec_search_size);

    // 创建 RecInfo 数组并设置字段
    jobjectArray recInfoArray = env->NewObjectArray(recSearchInfo->__Rec_search_size, h->cls_recInfo, nullptr);

    for (int i = 0; i < recSearchInfo->__Rec_search_size; i++) {
        jobject recInfoObj = env->AllocObject(h->cls_recInfo);
        _Rec_Info* recInfo = &(recSearchInfo->Rec_infos[i]);

        // 设置 RecInfo 对象的字段
        env->SetIntField(recInfoObj, h->fid_sourceId, recInfo->source_id);
        env->SetIntField(recInfoObj, h->fid_sourceChannelNum, recInfo->source_channel_Num);
        SetObjectStringFieldFromCstr(env, recInfoObj, h->fid_recInfoChannelId, recInfo->channelid);
        SetObjectStringFieldFromCstr(env, recInfoObj, h->fid_recInfoStreamId, recInfo->streamid);
        env->SetIntField(recInfoObj, h->fid_mediaType, recInfo->media_type);
        env->SetBooleanField(recInfoObj, h->fid_recordFlag, recInfo->Record_flag);
        env->SetLongField(recInfoObj, h->fid_earliestTimestamp, recInfo->earliestTimestamp);
        env->SetLongField(recInfoObj, h->fid_latestTimestamp, recInfo->latestTimestamp);

        // 将 RecInfo 对象放入数组
        env->SetObjectArrayElement(recInfoArray, i, recInfoObj);
    }

    // 设置 RecSearchInfo 对象的 recInfos 字段（即 RecInfo 数组）
    env->SetObjectField(recSearchInfoObj, h->fid_recInfos, recInfoArray);

    return recSearchInfoObj;
}




//PTZ 回调出参(应答)，从jobject对象转换为C结构体
void ParsePtzResponse(JNIEnv *env, jobject ptzResponse, _PTZ_RESPONSE_DAU* res) {
    if (nullptr == res || nullptr == ptzResponse) {
    	PrintLog("ParsePtzResponse ptzResponse: %p, res :%p\n", ptzResponse, res);
        return; 
    }

    JNIHandle *h = JNIHandle::GetInstance();
    memset(res, 0, sizeof(*res));

    ExtractOptionalStringField(env, ptzResponse, h->fid_ptzResponseDAU_presetTourToken, res->PresetTourToken, sizeof(res->PresetTourToken));
    //PtzStatus, 暂时不用，需要时再加映射

    //PTZConfigOptions
    jobject	objPtzConfigOptions = env->GetObjectField(ptzResponse, h->fid_ptzResponseDAU_ptzConfigOptions);
	if (objPtzConfigOptions == NULL) { 
        	PrintLog("GetObjectField fid_ptzResponseDAU_ptzConfigOptions fail\n");
	} else {

		res->PTZConfigOptions.ContinuousPanTiltVelocitySpacesize = env->GetIntField(objPtzConfigOptions, h->fid_ptzConfigurOption_continuousPanTiltVelocitySpaceSize);
		res->PTZConfigOptions.ContinuousZoomVelocitySpacesize = env->GetIntField(objPtzConfigOptions, h->fid_ptzConfigurOption_continuousZoomVelocitySpaceSize);

		jobject	objX_rangePT_GEN = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_xRangePT_GEN);
		if (objX_rangePT_GEN == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_xRangePT_GEN fail\n");
		} else {
			res->PTZConfigOptions.X_rangePT_GEN.range_MAX = env->GetFloatField(objX_rangePT_GEN, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.X_rangePT_GEN.range_MIN = env->GetFloatField(objX_rangePT_GEN, h->fid_ptzRange_rangeMin);
			PrintLog("res->PTZConfigOptions.X_rangePT_GEN.range_MAX :%f\n",res->PTZConfigOptions.X_rangePT_GEN.range_MAX );
			PrintLog("res->PTZConfigOptions.X_rangePT_GEN.range_MIN :%f\n",res->PTZConfigOptions.X_rangePT_GEN.range_MIN );
		}

		jobject	objY_rangePT_GEN = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_yRangePT_GEN);
		if (objY_rangePT_GEN == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_yRangePT_GEN fail\n");
		} else {
			res->PTZConfigOptions.Y_rangePT_GEN.range_MAX = env->GetFloatField(objY_rangePT_GEN, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.Y_rangePT_GEN.range_MIN = env->GetFloatField(objY_rangePT_GEN, h->fid_ptzRange_rangeMin);
		}

		jobject	objX_rangePT_FVO = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_xRangePT_FVO);
		if (objX_rangePT_FVO == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_xRangePT_FVO fail\n");
		} else {
			res->PTZConfigOptions.X_rangePT_FVO.range_MAX = env->GetFloatField(objX_rangePT_FVO, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.X_rangePT_FVO.range_MIN = env->GetFloatField(objX_rangePT_FVO, h->fid_ptzRange_rangeMin);
		}

		jobject	objY_rangePT_FVO = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_yRangePT_FVO);
		if (objY_rangePT_FVO == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_yRangePT_FVO fail\n");
		} else {
			res->PTZConfigOptions.Y_rangePT_FVO.range_MAX = env->GetFloatField(objY_rangePT_FVO, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.Y_rangePT_FVO.range_MIN = env->GetFloatField(objY_rangePT_FVO, h->fid_ptzRange_rangeMin);
		}

		jobject	objX_rangeZoom_GEN = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_xRangeZoom_GEN);
		if (objX_rangeZoom_GEN == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_xRangeZoom_GEN fail\n");
		} else {
			res->PTZConfigOptions.X_rangeZoom_GEN.range_MAX = env->GetFloatField(objX_rangeZoom_GEN, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.X_rangeZoom_GEN.range_MIN = env->GetFloatField(objX_rangeZoom_GEN, h->fid_ptzRange_rangeMin);
		}

		jobject	objX_rangeZoom_FVO = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_xRangeZoom_FVO);
		if (objX_rangeZoom_FVO == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_xRangeZoom_FVO fail\n");
		} else {
			res->PTZConfigOptions.X_rangeZoom_FVO.range_MAX = env->GetFloatField(objX_rangeZoom_FVO, h->fid_ptzRange_rangeMax);
			res->PTZConfigOptions.X_rangeZoom_FVO.range_MIN = env->GetFloatField(objX_rangeZoom_FVO, h->fid_ptzRange_rangeMin);
		}

		jobject	objPTZTimeOut = env->GetObjectField(objPtzConfigOptions, h->fid_ptzConfigurOption_ptzTimeout);
		if (objPTZTimeOut == NULL) {
			PrintLog("GetObjectField fid_ptzConfigurOption_ptzTimeout fail\n");
		} else {
			res->PTZConfigOptions.PTZTimeOut.timeout_MAX = env->GetFloatField(objPTZTimeOut, h->fid_ptzTimeout_timeoutMax);
			res->PTZConfigOptions.PTZTimeOut.timeout_MIN = env->GetFloatField(objPTZTimeOut, h->fid_ptzTimeout_timeoutMin);
		}
	}


    //_PTZ_PresetTourOption_DAU 暂时不用，需要时再加映射

    res->NeedinternalFree = env->GetBooleanField(ptzResponse, h->fid_ptzResponseDAU_needInternalFree);

    //PTZNodeList 暂时不用，需要时再加映射
    res->_size_PTZNode = 0;
    res->PTZNodeList = nullptr;

    //PresetList
    res->_size_Preset = 0; 
    res->PresetList = nullptr;

    //ConfigurationList
    res->_size_ConfigurationList = 0;
    res->ConfigurationList = 0;

    //PTZ_Move_Option
    jobject	objPtzMoveOption = env->GetObjectField(ptzResponse, h->fid_ptzResponseDAU_ptzMoveOption);
	if (objPtzMoveOption == NULL) {
        PrintLog("GetObjectField fid_ptzResponseDAU_ptzMoveOption fail\n");
	} else {

		jobject	objAbs_Pos_Range = env->GetObjectField(objPtzMoveOption, h->fid_ptzMoveOption_absPosRange);
		if (objAbs_Pos_Range == NULL) {
			PrintLog("GetObjectField fid_ptzMoveOption_absPosRange fail\n");
		} else {
			res->PTZ_Move_Option.Abs_Pos_Range.range_MAX = env->GetFloatField(objAbs_Pos_Range, h->fid_ptzRange_rangeMax);
			res->PTZ_Move_Option.Abs_Pos_Range.range_MIN = env->GetFloatField(objAbs_Pos_Range, h->fid_ptzRange_rangeMin);
		}

		jobject	objAbs_Speed_Range = env->GetObjectField(objPtzMoveOption, h->fid_ptzMoveOption_absSpeedRange);
		if (objAbs_Speed_Range == NULL) {
			PrintLog("GetObjectField fid_ptzMoveOption_absSpeedRange fail\n");
		} else {
			res->PTZ_Move_Option.Abs_Speed_Range.range_MAX = env->GetFloatField(objAbs_Speed_Range, h->fid_ptzRange_rangeMax);
			res->PTZ_Move_Option.Abs_Speed_Range.range_MIN = env->GetFloatField(objAbs_Speed_Range, h->fid_ptzRange_rangeMin);
		}

		jobject	objRel_Dis_Range = env->GetObjectField(objPtzMoveOption, h->fid_ptzMoveOption_relDisRange);
		if (objRel_Dis_Range == NULL) {
			PrintLog("GetObjectField fid_ptzMoveOption_relDisRange fail\n");
		} else {
			res->PTZ_Move_Option.Rel_Dis_Range.range_MAX = env->GetFloatField(objRel_Dis_Range, h->fid_ptzRange_rangeMax);
			res->PTZ_Move_Option.Rel_Dis_Range.range_MIN = env->GetFloatField(objRel_Dis_Range, h->fid_ptzRange_rangeMin);
		}

		jobject	objRel_Speed_Range = env->GetObjectField(objPtzMoveOption, h->fid_ptzMoveOption_relSpeedRange);
		if (objRel_Speed_Range == NULL) {
			PrintLog("GetObjectField fid_ptzMoveOption_relSpeedRange fail\n");
		} else {
			res->PTZ_Move_Option.Rel_Speed_Range.range_MAX = env->GetFloatField(objRel_Speed_Range, h->fid_ptzRange_rangeMax);
			res->PTZ_Move_Option.Rel_Speed_Range.range_MIN = env->GetFloatField(objRel_Speed_Range, h->fid_ptzRange_rangeMin);
		}

		jobject	objCon_Speed_Range = env->GetObjectField(objPtzMoveOption, h->fid_ptzMoveOption_conSpeedRange);
		if (objCon_Speed_Range == NULL) {
			PrintLog("GetObjectField fid_ptzMoveOption_conSpeedRange fail\n");
		} else {
			res->PTZ_Move_Option.Con_Speed_Range.range_MAX = env->GetFloatField(objCon_Speed_Range, h->fid_ptzRange_rangeMax);
			res->PTZ_Move_Option.Con_Speed_Range.range_MIN = env->GetFloatField(objCon_Speed_Range, h->fid_ptzRange_rangeMin);
		}
	}

    //PTZ_Image
    jobject	objPtzImage = env->GetObjectField(ptzResponse, h->fid_ptzResponseDAU_ptzImage);
	if (objPtzImage == NULL) {
        PrintLog("GetObjectField fid_ptzResponseDAU_ptzImage fail\n");
	} else {

		res->PTZ_Image._autoFocusMode = env->GetIntField(objPtzImage, h->fid_ptzImageSetParam_autoFocusMode);
		res->PTZ_Image._focusDefSpeed = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_focusDefSpeed);
		res->PTZ_Image._focusNearLimit = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_focusNearLimit);
		res->PTZ_Image._focusFarLimit = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_focusFarLimit);
		res->PTZ_Image._exposureTime = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_exposureTime);
		res->PTZ_Image._exposureMode = env->GetIntField(objPtzImage, h->fid_ptzImageSetParam_exposureMode);
		res->PTZ_Image._backlightCompensationMode = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_backlightCompensationMode);
		res->PTZ_Image._backlightCompensationLevel = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_backlightCompensationLevel);
		res->PTZ_Image._brightness = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_brightness);
		res->PTZ_Image._colorSaturation = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_colorSaturation);
		res->PTZ_Image._contrast = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_contrast);
		res->PTZ_Image._Sharpness = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_sharpness);
		res->PTZ_Image._irCutFilter = env->GetIntField(objPtzImage, h->fid_ptzImageSetParam_irCutFilter);
		res->PTZ_Image._wideDynamicRangeMode = env->GetIntField(objPtzImage, h->fid_ptzImageSetParam_wideDynamicRangeMode);
		res->PTZ_Image._wideDynamicRangeLevel = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_wideDynamicRangeLevel);
		res->PTZ_Image._Gain = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_gain);
		res->PTZ_Image._Iris = env->GetFloatField(objPtzImage, h->fid_ptzImageSetParam_iris);
	}

    //PTZ_imgOption
    jobject	objPtzImgOption = env->GetObjectField(ptzResponse, h->fid_ptzResponseDAU_ptzImgOption);
	if (objPtzImgOption == NULL) {
        PrintLog("GetObjectField fid_ptzResponseDAU_ptzImgOption fail\n");
	} else {
        	PrintLog("GetObjectField fid_ptzResponseDAU_ptzImgOption 1111\n");
		res->PTZ_imgOption._autoFocusMode = env->GetIntField(objPtzImgOption, h->fid_ptzImageOption_autoFocusMode);
		PrintLog("GetObjectField fid_ptzImageOption_autoFocusMode success\n");

		jobject	obj_focusDefSpeed = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_focusDefSpeed);
		if (obj_focusDefSpeed == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_focusDefSpeed fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_focusDefSpeed success\n");
			res->PTZ_imgOption._focusDefSpeed.range_MAX = env->GetFloatField(obj_focusDefSpeed, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._focusDefSpeed.range_MIN = env->GetFloatField(obj_focusDefSpeed, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_focusNearLimit = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_focusNearLimit);
		if (obj_focusNearLimit == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_focusNearLimit fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_focusNearLimit success\n");
			res->PTZ_imgOption._focusNearLimit.range_MAX = env->GetFloatField(obj_focusNearLimit, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._focusNearLimit.range_MIN = env->GetFloatField(obj_focusNearLimit, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_focusFarLimit = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_focusFarLimit);
		if (obj_focusFarLimit == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_focusFarLimit fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_focusFarLimit success\n");
			res->PTZ_imgOption._focusFarLimit.range_MAX = env->GetFloatField(obj_focusFarLimit, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._focusFarLimit.range_MIN = env->GetFloatField(obj_focusFarLimit, h->fid_ptzRange_rangeMin);
		}

		res->PTZ_imgOption._exposureMode = env->GetIntField(objPtzImgOption, h->fid_ptzImageOption_exposureMode);

		jobject	obj_exposureTime = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_exposureTime);
		if (obj_exposureTime == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_exposureTime fail\n");
		} else { 
			PrintLog("GetObjectField fid_ptzImageOption_exposureTime success\n");
			res->PTZ_imgOption._exposureTime.range_MAX = env->GetFloatField(obj_exposureTime, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._exposureTime.range_MIN = env->GetFloatField(obj_exposureTime, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_exposure_gain = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_exposureGain);
		if (obj_exposure_gain == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_exposureGain fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_exposureGain success\n");
			res->PTZ_imgOption._exposure_gain.range_MAX = env->GetFloatField(obj_exposure_gain, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._exposure_gain.range_MIN = env->GetFloatField(obj_exposure_gain, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_exposure_iris = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_exposureIris);
		if (obj_exposure_iris == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_exposureIris fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_exposureIris success\n");
			res->PTZ_imgOption._exposure_iris.range_MAX = env->GetFloatField(obj_exposure_iris, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._exposure_iris.range_MIN = env->GetFloatField(obj_exposure_iris, h->fid_ptzRange_rangeMin);
		}


		res->PTZ_imgOption._backlightCompensationMode = env->GetIntField(objPtzImgOption, h->fid_ptzImageOption_backlightCompensationMode);

		jobject	obj_backlightCompensationLevel = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_backlightCompensationLevel);
		if (obj_backlightCompensationLevel == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_backlightCompensationLevel fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_backlightCompensationLevel success\n");
			res->PTZ_imgOption._backlightCompensationLevel.range_MAX = env->GetFloatField(obj_backlightCompensationLevel, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._backlightCompensationLevel.range_MIN = env->GetFloatField(obj_backlightCompensationLevel, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_brightness = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_brightness);
		if (obj_brightness == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_brightness fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_brightness success\n");
			res->PTZ_imgOption._brightness.range_MAX = env->GetFloatField(obj_brightness, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._brightness.range_MIN = env->GetFloatField(obj_brightness, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_colorSaturation = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_colorSaturation);
		if (obj_colorSaturation == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_colorSaturation fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_colorSaturation success\n");
			res->PTZ_imgOption._colorSaturation.range_MAX = env->GetFloatField(obj_colorSaturation, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._colorSaturation.range_MIN = env->GetFloatField(obj_colorSaturation, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_contrast = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_contrast);
		if (obj_contrast == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_contrast fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_contrast success\n");
			res->PTZ_imgOption._contrast.range_MAX = env->GetFloatField(obj_contrast, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._contrast.range_MIN = env->GetFloatField(obj_contrast, h->fid_ptzRange_rangeMin);
		}
		jobject	obj_Sharpness = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_sharpness);
		if (obj_Sharpness == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_sharpness fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_sharpness success\n");
			res->PTZ_imgOption._Sharpness.range_MAX = env->GetFloatField(obj_Sharpness, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._Sharpness.range_MIN = env->GetFloatField(obj_Sharpness, h->fid_ptzRange_rangeMin);
		}

		jobject	obj_wideDynamicRangelevel = env->GetObjectField(objPtzImgOption, h->fid_ptzImageOption_wideDynamicRangeLevel);
		if (obj_wideDynamicRangelevel == NULL) {
			PrintLog("GetObjectField fid_ptzImageOption_wideDynamicRangeLevel fail\n");
		} else {
			PrintLog("GetObjectField fid_ptzImageOption_wideDynamicRangeLevel success\n");
			res->PTZ_imgOption._wideDynamicRangelevel.range_MAX = env->GetFloatField(obj_wideDynamicRangelevel, h->fid_ptzRange_rangeMax);
			res->PTZ_imgOption._wideDynamicRangelevel.range_MIN = env->GetFloatField(obj_wideDynamicRangelevel, h->fid_ptzRange_rangeMin);
		}
	}
}

/**
 * 辅助函数：提取字符串字段，仅在字段不为空时进行赋值
 */
void ExtractStringFieldIfPresent(JNIEnv *env, jobject obj, jfieldID fieldID, char* output, size_t output_size) {
    jstring str = (jstring) env->GetObjectField(obj, fieldID);
    if (str != nullptr) {
        const char* pStr = env->GetStringUTFChars(str, JNI_FALSE);
        if (pStr != nullptr) {
            // 安全地拷贝字符串，避免缓冲区溢出
            strncpy(output, pStr, output_size - 1);
            output[output_size - 1] = '\0';  // 确保字符串以NULL结尾
            env->ReleaseStringUTFChars(str, pStr);
        }
    }
}

ParseServerDevInfoPlus ParseServerDevInfoUpdate(JNIEnv *env, jobject serverDevInfoPlus) {
    ParseServerDevInfoPlus rs{};  // 初始化返回值
    JNIHandle *h = JNIHandle::GetInstance();

    // 提取设备类型，如果需要可以添加条件进行判断
    rs.info._devicetype = env->GetIntField(serverDevInfoPlus, h->fid_deviceType);

    // 提取并更新字符串字段，仅在字段不为空时进行更新
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devName, rs.info._dev_name, sizeof(rs.info._dev_name));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devSerial, rs.info._dev_serial, sizeof(rs.info._dev_serial));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devHardwareId, rs.info._dev_hardwareid, sizeof(rs.info._dev_hardwareid));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devFirmwareVersion, rs.info._dev_firmwareVersion, sizeof(rs.info._dev_firmwareVersion));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devManufacturer, rs.info._dev_m_manufacturer, sizeof(rs.info._dev_m_manufacturer));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devMode, rs.info._dev_mode, sizeof(rs.info._dev_mode));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devIp, rs.info._dev_ip, sizeof(rs.info._dev_ip));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devSoapPort, rs.info._dev_soap_port, sizeof(rs.info._dev_soap_port));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devLoginUsername, rs.info._dev_login_username, sizeof(rs.info._dev_login_username));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devLoginPassword, rs.info._dev_login_password, sizeof(rs.info._dev_login_password));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devEthName, rs.info._dev_ethname, sizeof(rs.info._dev_ethname));
    ExtractStringFieldIfPresent(env, serverDevInfoPlus, h->fid_devEthMac, rs.info._dev_ethmac, sizeof(rs.info._dev_ethmac));

    return rs;
}
// 提取公共的获取字符串并赋值给 _Rec_Info 的函数
void SetStringField(JNIEnv* env, jobject recInfoObj, jfieldID fieldId, char* dest, size_t destSize) {
    jstring str = static_cast<jstring>(env->GetObjectField(recInfoObj, fieldId));
    if (str != nullptr) {
        const char* utfStr = env->GetStringUTFChars(str, nullptr);
        strncpy(dest, utfStr, destSize - 1);
        env->ReleaseStringUTFChars(str, utfStr);
    }
}

void logRecInfoDetails(JNIEnv* env, jobject recInfoObj, JNIHandle* h, int index) {
    // 打印 RecInfo 的具体内容
    int sourceId = env->GetIntField(recInfoObj, h->fid_sourceId);
    int sourceChannelNum = env->GetIntField(recInfoObj, h->fid_sourceChannelNum);

    jstring channelIdStr = static_cast<jstring>(env->GetObjectField(recInfoObj, h->fid_recInfoChannelId));
    const char* channelId = (channelIdStr != nullptr) ? env->GetStringUTFChars(channelIdStr, nullptr) : "null";

    jstring streamIdStr = static_cast<jstring>(env->GetObjectField(recInfoObj, h->fid_recInfoStreamId));
    const char* streamId = (streamIdStr != nullptr) ? env->GetStringUTFChars(streamIdStr, nullptr) : "null";

    int mediaType = env->GetIntField(recInfoObj, h->fid_mediaType);
    bool recordFlag = env->GetBooleanField(recInfoObj, h->fid_recordFlag);
    long earliestTimestamp = env->GetLongField(recInfoObj, h->fid_earliestTimestamp);
    long latestTimestamp = env->GetLongField(recInfoObj, h->fid_latestTimestamp);

    // 打印 RecInfo 的详细信息
    PrintLog("RecInfo[%d]: sourceId = %d, sourceChannelNum = %d, channelId = %s, streamId = %s, mediaType = %d, recordFlag = %d, earliestTimestamp = %ld, latestTimestamp = %ld\n",
             index, sourceId, sourceChannelNum, channelId, streamId, mediaType, recordFlag, earliestTimestamp, latestTimestamp);

    // 释放字符串资源
    if (channelIdStr != nullptr) {
        env->ReleaseStringUTFChars(channelIdStr, channelId);
    }
    if (streamIdStr != nullptr) {
        env->ReleaseStringUTFChars(streamIdStr, streamId);
    }
}

// 获取特定字段并赋值
void convertToRecSearchInfo(JNIEnv* env, jobject recSearchInfoObj, void* _Rec_reserve_info) {
    if (recSearchInfoObj == nullptr) {
        PrintLog("Error: recSearchInfoObj is null.\n");
        return;
    }

    Rec_Search_info* recSearchInfo = static_cast<Rec_Search_info*>(_Rec_reserve_info);
    if (recSearchInfo == nullptr) {
        PrintLog("Error: Rec_Search_info is null.\n");
        return;
    }

    JNIHandle* h = JNIHandle::GetInstance();
    if (h == nullptr || h->fid_checkAll == nullptr || h->fid_recSearchSize == nullptr || h->fid_recInfos == nullptr) {
        PrintLog("Error: JNIHandle instance or field IDs are not initialized.\n");
        return;
    }

    // 获取 checkAll 字段
    jboolean checkAll = env->GetBooleanField(recSearchInfoObj, h->fid_checkAll);
    recSearchInfo->cheackall = checkAll;

    // 获取 recSearchSize 字段
    jint recSearchSize = env->GetIntField(recSearchInfoObj, h->fid_recSearchSize);
    recSearchInfo->__Rec_search_size = recSearchSize;

    // 获取 recInfos 数组
    jobjectArray recInfoArray = static_cast<jobjectArray>(env->GetObjectField(recSearchInfoObj, h->fid_recInfos));
    if (recInfoArray == nullptr) {
        PrintLog("Error: recInfos array is null.\n");
        return;
    }

    jint recInfoArraySize = env->GetArrayLength(recInfoArray);
    if (recInfoArraySize <= 0) {
        PrintLog("Error: recInfo array size is invalid (%d).\n", recInfoArraySize);
        return;
    }

    // 分配 Rec_infos 数组内存
    recSearchInfo->Rec_infos = new (std::nothrow) _Rec_Info[recInfoArraySize];
    if (recSearchInfo->Rec_infos == nullptr) {
        PrintLog("Error: Memory allocation failed for Rec_infos.\n");
        return;
    }

    // 遍历数组，转换 Rec_Info
    for (int i = 0; i < recInfoArraySize; i++) {
        jobject recInfoObj = env->GetObjectArrayElement(recInfoArray, i);
        if (recInfoObj == nullptr) {
            PrintLog("Error: RecInfo at index %d is null.\n", i);
            continue;
        }

        _Rec_Info* recInfo = &recSearchInfo->Rec_infos[i];

        // 填充 _Rec_Info 数据
        recInfo->source_id = env->GetIntField(recInfoObj, h->fid_sourceId);
        recInfo->source_channel_Num = env->GetIntField(recInfoObj, h->fid_sourceChannelNum);
        SetStringField(env, recInfoObj, h->fid_recInfoChannelId, recInfo->channelid, sizeof(recInfo->channelid));
        SetStringField(env, recInfoObj, h->fid_recInfoStreamId, recInfo->streamid, sizeof(recInfo->streamid));
        recInfo->media_type = env->GetIntField(recInfoObj, h->fid_mediaType);
        recInfo->Record_flag = env->GetBooleanField(recInfoObj, h->fid_recordFlag);
        recInfo->earliestTimestamp = env->GetLongField(recInfoObj, h->fid_earliestTimestamp);
        recInfo->latestTimestamp = env->GetLongField(recInfoObj, h->fid_latestTimestamp);

        env->DeleteLocalRef(recInfoObj);
    }

    PrintLog("convertToRecSearchInfo completed: checkAll = %d, recSearchSize = %d, recInfoArraySize = %d\n",
             recSearchInfo->cheackall, recSearchInfo->__Rec_search_size, recInfoArraySize);
}


void ConvertsRecSearchEventInfo(JNIEnv* env, jobject recSearchEventInfoObj, void* _Rec_reserve_info) {
    // 将 void* 转换为 Rec_Search_event_info
    Rec_Search_event_info* recSearchEventInfo = static_cast<Rec_Search_event_info*>(_Rec_reserve_info);
    if (recSearchEventInfo == nullptr) {
        return;
    }

    // 获取 JNIHandle 实例
    JNIHandle* h = JNIHandle::GetInstance();

    // 设置基本字段
    recSearchEventInfo->source_id = env->GetIntField(recSearchEventInfoObj, h->fid_sourceIdentifier);
    recSearchEventInfo->source_channel_Num = env->GetIntField(recSearchEventInfoObj, h->fid_channelNumber);

    // 设置字符串字段（channelId 和 streamId）使用 SetStringField
    SetStringField(env, recSearchEventInfoObj, h->fid_channelIdentifier, recSearchEventInfo->channelid, sizeof(recSearchEventInfo->channelid));
    SetStringField(env, recSearchEventInfoObj, h->fid_streamIdentifier, recSearchEventInfo->streamid, sizeof(recSearchEventInfo->streamid));

    // 设置布尔字段
    recSearchEventInfo->Record_flag = env->GetBooleanField(recSearchEventInfoObj, h->fid_isRecording);

    // 设置时间戳字段
    recSearchEventInfo->startTimestamp = env->GetLongField(recSearchEventInfoObj, h->fid_eventStartTimestamp);
    recSearchEventInfo->endTimestamp = env->GetLongField(recSearchEventInfoObj, h->fid_eventEndTimestamp);

    // 获取 file_size 字段并打印
    jint fileSize = env->GetIntField(recSearchEventInfoObj, h->fid_eventFileSize);

    // 这里将 fileSize 赋值给结构体的 file_size 字段
    recSearchEventInfo->file_size = fileSize;

    // 处理 RecEventInfo 数组
    int eventInfoCount = recSearchEventInfo->file_size; // 假设 file_size 是 RecEventInfo 数组的大小

    // 为 Rec_eve_infos 数组分配内存
    recSearchEventInfo->Rec_eve_infos = new _Rec_event_Info[eventInfoCount];  // 使用 new 分配内存

    jobjectArray eventInfoArray = static_cast<jobjectArray>(env->GetObjectField(recSearchEventInfoObj, h->fid_eventInfoArray));

    // 填充 RecEventInfo 数组
    if (eventInfoArray != nullptr) {
        for (int i = 0; i < eventInfoCount; ++i) {
            jobject recEventInfoObj = env->GetObjectArrayElement(eventInfoArray, i);
            if (recEventInfoObj == nullptr) {
                continue;  // 如果 RecEventInfo 对象为空，跳过该索引
            }

            _Rec_event_Info* recEventInfo = &(recSearchEventInfo->Rec_eve_infos[i]);

            // 设置 RecEventInfo 字段
            recEventInfo->media_type = env->GetIntField(recEventInfoObj, h->fid_mediaTypeField);
            recEventInfo->startTimestamp = env->GetLongField(recEventInfoObj, h->fid_startTimestamp);
            recEventInfo->endTimestamp = env->GetLongField(recEventInfoObj, h->fid_endTimestamp);
            // 删除局部引用
            env->DeleteLocalRef(recEventInfoObj);
        }
    }
}
void ConvertsRecUrlInfo(JNIEnv* env, jobject recSearchEventInfoObj, void* _Rec_reserve_info) {
    // 强制转换为 Rec_Uri_info 指针
    Rec_Uri_info* urlInfo = static_cast<Rec_Uri_info*>(_Rec_reserve_info);

    if (urlInfo == nullptr) {
        return;
    }

    // 获取 JNIHandle 实例
    JNIHandle* h = JNIHandle::GetInstance();

    if (h == nullptr) {
        return;
    }

    // 获取 dataSize 字段
    jint dataSize = env->GetIntField(recSearchEventInfoObj, h->fid_dataSize);
    if (dataSize == 0) {
        return;
    }

    // 获取 uriInfo 字段
    jstring uriInfo = (jstring) env->GetObjectField(recSearchEventInfoObj, h->fid_uriInfo);
    const char* uriInfoStr = nullptr;
    if (uriInfo != nullptr) {
        uriInfoStr = env->GetStringUTFChars(uriInfo, nullptr);
    }

    // 检查是否已为 urlInfo->uri_info 分配内存
    if (urlInfo->uri_info == nullptr) {
        urlInfo->uri_info = new char[1024];  // 分配内存
        memset(urlInfo->uri_info, 0x00, 1024);
        if (urlInfo->uri_info == nullptr) {
            return;
        }
    }

    // 设置 _data_size 和 uri_info
    urlInfo->_data_size = dataSize;

    // 设置 uri_info 字段的值
    if (uriInfoStr != nullptr) {
        memcpy((void*)urlInfo->uri_info, (void*)uriInfoStr, dataSize);
    }

    // 释放 URI 字符串内存
    if (uriInfo != nullptr && uriInfoStr != nullptr) {
        env->ReleaseStringUTFChars(uriInfo, uriInfoStr);
    }
}




































